<script lang="ts" setup>
import { QForm, QTable, type FormItemRows, type TableColums } from '@meetjs/element-plus-kit'
import { Calendar, User } from '@element-plus/icons-vue'

import { warnBox } from '@/utils/utils'
import { ElMessage } from 'element-plus'

import { ManagementStatus, type AthleteQueryParams } from '@/api/athlete/types'
import { getAthleteListApi, deleteAthleteApi, exportAthleteListApi } from '@/api/athlete/index'
import { toViewModelListAsync, type AthleteViewModel } from '@/api/athlete/transformer'
import { baseFormOptions, expandedFormOptions, formValue } from './formConfig'
import { useRouter } from 'vue-router'
import arrowDownIcon from '@/assets/athlete/icons/arrow-down.svg?url'
import { useAthleteListStore } from '@/store/athlete/athleteList'
import { addEnterSearchToFormOptions } from '@/utils/formHelper'
import { useDict } from '@/composables/useDict'
import { useDictStore } from '@/store/dict'

const router = useRouter()
const athleteStore = useAthleteListStore()

const { orgCascadeOptions } = useDict([])

const dictStore = useDictStore()

// 展开折叠状态
const isExpanded = ref(false)

// 表单引用
const formRef = useTemplateRef<{
	resetFields: () => void
	validate: () => Promise<boolean>
}>('formRef')

//  使用工厂函数创建支持回车搜索的表单配置
const searchableBaseOptions = computed(() => addEnterSearchToFormOptions(baseFormOptions.value, getTableData))

const searchableExpandedOptions = computed(() => addEnterSearchToFormOptions(expandedFormOptions.value, getTableData))

// 计算当前显示的表单字段
const currentFormOptions = computed(() => {
	return isExpanded.value ? [...searchableBaseOptions.value, ...searchableExpandedOptions.value] : searchableBaseOptions.value
})

// 切换展开折叠状态
const toggleExpanded = () => {
	isExpanded.value = !isExpanded.value
}

// 过渡动画钩子函数
const onEnter = (el: Element) => {
	const element = el as HTMLElement
	element.style.height = '0'
	element.style.overflow = 'hidden'
	// 强制浏览器重绘
	element.offsetHeight
	// 设置目标高度
	element.style.height = element.scrollHeight + 'px'
}

const onAfterEnter = (el: Element) => {
	const element = el as HTMLElement
	// 动画结束后移除高度限制，让内容自适应
	element.style.height = 'auto'
	element.style.overflow = 'visible'
}

const onLeave = (el: Element) => {
	const element = el as HTMLElement
	// 设置当前高度
	element.style.height = element.scrollHeight + 'px'
	element.style.overflow = 'hidden'
	// 强制浏览器重绘
	element.offsetHeight
	// 收起到 0
	element.style.height = '0'
}

const onAfterLeave = (el: Element) => {
	const element = el as HTMLElement
	element.style.overflow = 'visible'
}

// 重置表单 - 使用QForm内置方法
const handleReset = () => {
	formValue.value = {} // 直接清空所有字段
	getTableData()
}

// table
const loading = ref(false)
const page = ref({
	currentPage: 1,
	pageSize: 10,
	total: 0
})
const tableData = ref<AthleteViewModel[]>([])

const columns = ref<TableColums[]>([
	{
		type: 'selection',
		width: 55,
		align: 'center'
	},
	{
		type: 'index',
		label: '序号',
		align: 'center',
		width: 60
	},
	{
		prop: 'athlete',
		label: '运动员',
		width: 200
	},
	// {
	// 	label: '性别',
	// 	prop: 'sexLabel',
	// 	width: 80,
	// 	align: 'center'
	// },
	{
		label: '身份证号',
		prop: 'idNumber',
		width: 180,
		align: 'center'
	},
	// 注册状态
	{
		label: '注册状态',
		prop: 'approvalStatusLabel',
		width: 120,
		align: 'center'
	},
	// 状态
	{
		label: '状态',
		prop: 'statusLabel',
		width: 120,
		align: 'center'
	},
	{
		label: '注册证号',
		prop: 'registerNumber',
		width: 150,
		align: 'center'
	},
	{
		label: '注册项目',
		prop: 'registerProjectLabel',
		width: 120,
		align: 'center'
	},
	{
		label: '在训单位',
		prop: 'trainOrgLabel',
		width: 200,
		align: 'center'
	},
	{
		label: '注册单位',
		prop: 'registerOrgLabel',
		width: 200,
		align: 'center'
	},
	{
		label: '教练',
		prop: 'coachName',
		width: 100,
		align: 'center'
	},
	{
		label: '学籍卡号',
		prop: 'studentNumber',
		width: 150,
		align: 'center'
	},
	{
		label: '注册年度',
		prop: 'registerYear',
		width: 100,
		align: 'center'
	},
	{
		label: '首次注册年度',
		prop: 'firstRegisterYear',
		width: 130,
		align: 'center'
	},
	{
		label: '协议起始时间',
		prop: 'agreementStart',
		width: 120,
		align: 'center'
	},
	{
		label: '协议终止时间',
		prop: 'agreementEnd',
		width: 120,
		align: 'center'
	},
	{
		label: '记录时间',
		prop: 'createTime',
		minWidth: 160,
		align: 'center'
	},
	{
		prop: 'action',
		fixed: 'right',
		label: '操作',
		align: 'center'
	}
])

const handleSearch = () => {
	// 重置分页
	page.value.currentPage = 1
	getTableData()
}

const getTableData = async () => {
	try {
		loading.value = true

		console.log(page.value)

		//  通过 Store 加载数据，缓存到全局状态
		athleteStore.pagination.currentPage = page.value.currentPage
		athleteStore.pagination.pageSize = page.value.pageSize

		console.log('formValue:', formValue.value)

		const queryParams: AthleteQueryParams = {
			pageNum: page.value.currentPage,
			pageSize: page.value.pageSize,
			...formValue.value
		}

		if (queryParams.approvalStatus === ManagementStatus.ALL) {
			delete queryParams.approvalStatus
		}

		await athleteStore.loadList(queryParams)

		//  使用异步转换，自动加载所有运动员的照片文件信息
		tableData.value = await toViewModelListAsync(athleteStore.list)
		page.value.total = athleteStore.pagination.total

		console.log('tableData:', tableData.value)
	} finally {
		loading.value = false
	}
}

// 查看详情
const handleDetail = (row: AthleteViewModel) => {
	if (!row.id) {
		ElMessage.warning('运动员ID不存在')
		return
	}

	//  设置当前查看的运动员到 Store
	athleteStore.setCurrentById(row.id)

	router.push({
		path: '/athleteFirst/detail',
		query: { id: row.id }
	})
}

// 批量操作相关
const selectedRows = ref<AthleteViewModel[]>([])

const handleBatchDelete = async () => {
	if (selectedRows.value.length === 0) {
		ElMessage.warning('请先选择要删除的运动员')
		return
	}

	try {
		await warnBox({
			message: `确定要删除选中的 ${selectedRows.value.length} 个运动员吗？`
		})

		// 显示加载状态
		const loadingInstance = ElMessage({
			message: '正在删除...',
			type: 'info',
			duration: 0
		})

		try {
			// 使用 Promise.all 并发调用单个删除接口
			const deletePromises = selectedRows.value.map(row => {
				if (!row.id) {
					console.warn('运动员ID为空，跳过删除', row)
					return Promise.resolve() // 跳过无效ID
				}
				return deleteAthleteApi(row.id)
			})

			// 等待所有删除操作完成
			const results = await Promise.allSettled(deletePromises)

			// 统计成功和失败的数量
			const successCount = results.filter(r => r.status === 'fulfilled').length
			const failedCount = results.filter(r => r.status === 'rejected').length

			// 关闭加载提示
			loadingInstance.close()

			// 显示结果
			if (failedCount === 0) {
				ElMessage.success(`成功删除 ${successCount} 条记录`)
			} else if (successCount === 0) {
				ElMessage.error(`删除失败，请重试`)
			} else {
				ElMessage.warning(`成功删除 ${successCount} 条，失败 ${failedCount} 条`)
			}

			// 清空选中项并刷新表格
			selectedRows.value = []
			await getTableData()
		} catch (error) {
			loadingInstance.close()
			ElMessage.error('删除失败，请重试')
			console.error('批量删除错误:', error)
		}
	} catch (error) {
		// 用户取消操作
	}
}

const handleBatchExport = async () => {
	try {
		// 显示加载状态
		const loadingInstance = ElMessage({
			message: '正在导出...',
			type: 'info',
			duration: 0
		})

		try {
			// 构建导出参数：包含搜索条件 + 可选的选中ID
			const exportParams: any = {
				...formValue.value // 搜索条件
			}

			// 如果有选中的运动员，添加ID参数
			const ids = selectedRows.value.map(row => row.id).filter(Boolean) as Array<string | number>
			if (ids.length > 0) {
				exportParams.ids = ids.join(',') // 将ID数组转换为逗号分隔的字符串
			}

			// 调用导出API，后端根据参数自动决定导出策略
			const result = await exportAthleteListApi(exportParams)

			//  result 是 {filename: string, data: Blob} 对象
			const blob = result.data
			const filename = result.filename || `运动员导出_${new Date().getTime()}.xlsx`

			// 创建下载链接
			const url = window.URL.createObjectURL(blob)
			const link = document.createElement('a')
			link.href = url
			link.download = filename
			link.style.display = 'none'
			document.body.appendChild(link)
			link.click()

			// 清理
			document.body.removeChild(link)
			window.URL.revokeObjectURL(url)

			// 关闭加载提示
			loadingInstance.close()
			ElMessage.success('导出成功')
		} catch (error) {
			loadingInstance.close()
			ElMessage.error('导出失败，请重试')
			console.error('批量导出错误:', error)
		}
	} catch (error) {
		console.error('导出失败:', error)
	}
}

const handleSelectionChange = (selection: AthleteViewModel[]) => {
	selectedRows.value = selection
}

onMounted(async () => {
	await getTableData()

	console.log('searchableExpandedOptions:', searchableExpandedOptions.value)
})
</script>
<template>
	<div class="h-full flex-col relative flex table-page-box">
		<!-- 筛选区域 -->
		<div class="p-5 mb-4 bg-primary search-form-container">
			<!-- 基础表单字段 -->
			<div class="form-base">
				<QForm
					ref="formRef"
					:model="formValue"
					:form-options="searchableBaseOptions"
					label-position="left"
					:buttons="[]"
					:col="6"
					:gutter="16"
					@search="getTableData"
					@reset="handleReset"
				/>
			</div>

			<div>
				<!-- 扩展表单字段（带过渡动画） -->
				<transition
					name="expand"
					@enter="onEnter"
					@afterEnter="onAfterEnter"
					@leave="onLeave"
					@afterLeave="onAfterLeave"
				>
					<div
						v-show="isExpanded"
						class="form-expanded"
					>
						<QForm
							:model="formValue"
							:form-options="searchableExpandedOptions"
							label-position="left"
							:buttons="[]"
							:col="6"
							:gutter="16"
							@search="getTableData"
							@reset="handleReset"
						/>
					</div>
				</transition>
			</div>

			<!-- 按钮组 -->
			<div class="flex justify-end items-center gap-2">
				<el-button
					type="primary"
					@click="handleSearch"
				>
					搜索
				</el-button>
				<el-button @click="handleReset">重置</el-button>
				<div
					class="p-1 flex items-center space-x-[6px] cursor-pointer hover:opacity-80 transition-opacity"
					@click="toggleExpanded"
				>
					<span class="text-sm text-tertiary">{{ isExpanded ? '收起' : '展开' }}</span>
					<img
						:src="arrowDownIcon"
						class="size-4 transition-transform duration-300 ease-in-out"
						:class="isExpanded ? 'rotate-180' : 'rotate-0'"
						alt="arrow-down"
					/>
				</div>
			</div>
		</div>

		<!-- 表格区域 -->
		<div class="flex-1 relative bg-primary p-5 rounded flex flex-col">
			<!-- 表格头部 -->
			<div class="card-header mb-5">
				<div class="flex items-center justify-between">
					<h2 class="text-base font-500 text-primary">运动员列表</h2>
					<div class="flex items-center gap-2">
						<el-button
							type="danger"
							plain
							:disabled="selectedRows.length === 0"
							class="w-[108px] h-8 text-sm bg-white! border-danger! text-danger!"
							@click="handleBatchDelete"
						>
							<el-icon class="w-3.5 h-3.5 mr-1.5">
								<Calendar />
							</el-icon>
							批量删除
						</el-button>
						<el-button
							plain
							class="w-[88px] h-8 text-sm"
							@click="handleBatchExport"
						>
							批量导出
						</el-button>
					</div>
				</div>
			</div>

			<!-- 表格内容 -->
			<div class="table-box p0!">
				<QTable
					:data="tableData"
					:columns="columns"
					:page="page"
					:loading="loading"
					@pageChange="getTableData"
					@selectionChange="handleSelectionChange"
				>
					<!--  头像列 -->
					<template #athlete="{ row }">
						<div class="flex items-center gap-4">
							<img
								:src="row.personPhotoFile?.filePath"
								alt="avatar"
								class="size-8 rounded-full"
							/>
							<div class="">
								<div class="text-sm font-500 text-primary mb-0.5">{{ row.athleteName }}</div>
								<div class="text-xs text-secondary">{{ row.sexLabel }}·{{ row.age }}</div>
							</div>
							<div>
								<div
									v-if="row.changeTypes.includes(1)"
									class="table-tag h-[20px] bg-#E8F3FF text-brand mb-1"
								>
									单位变更
								</div>
								<div
									v-if="row.changeTypes.includes(2)"
									class="table-tag h-[20px] bg-#E8FFFB text-[#14C9C9]"
								>
									项目变更
								</div>
							</div>
						</div>
					</template>

					<template #action="{ row }">
						<el-button
							type="primary"
							link
							@click="handleDetail(row)"
						>
							查看
						</el-button>
					</template>
				</QTable>
			</div>
		</div>
	</div>
</template>

<style lang="scss" scoped>
/* 搜索表单容器 */
.search-form-container {
	flex-shrink: 0; // 禁止在 flex 布局中被压缩
	min-height: 160px; // 设置最小高度，防止被压缩（基础表单 + 按钮）
	overflow: visible; // 允许内容溢出，但保持最小高度
}

/* 基础表单区域 */
.form-base {
	min-height: 80px; // 确保基础表单区域也有最小高度
}

/* 扩展表单区域 */
.form-expanded {
	opacity: 1;
	transition:
		height 0.3s ease-in-out,
		opacity 0.3s ease-in-out;
}

/* 进入和离开的过渡效果 */
.expand-enter-active,
.expand-leave-active {
	overflow: hidden;
	transition:
		height 0.3s cubic-bezier(0.4, 0, 0.2, 1),
		opacity 0.3s ease-in-out;
}
.expand-enter-from,
.expand-leave-to {
	opacity: 0;
}
.expand-enter-to,
.expand-leave-from {
	opacity: 1;
}

/* 表格区域 - 确保不会被压缩且可以滚动 */
.table-box {
	flex: 1;
	min-height: 0; // 允许 flex 子项滚动
	overflow: auto;
}
</style>
